﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Urb.Weather.Core;
using Urb.Weather.Core.Util;

namespace Urb.Weather.Wunderground.IntegrationTests
{
    [TestClass]
    public class GettingAndAnalyzingCurrentWundergroundWeatherRealData
    {
        private WundergroundResponseAnalyzer responseAnalyzer;

        private const int minServiceQueryInterval = 2000;
        private static DateTime? lastServiceQueryTime;

        [TestInitialize]
        public void TestInitialize()
        {
            responseAnalyzer = new WundergroundResponseAnalyzer();
        }

        [TestMethod]
        public void WundergroundWeather_Wroclaw_CurrentConditions()
        {
            CurrentConditions("Wroclaw,Poland");
        }

        [TestMethod]
        public void WundergroundWeather_Wroclaw_Forecast()
        {
            Forecast("Wroclaw,Poland");
        }

        private void CurrentConditions(string location)
        {
            if (lastServiceQueryTime.HasValue && (DateTime.Now - lastServiceQueryTime.Value).TotalMilliseconds < minServiceQueryInterval)
                Thread.Sleep(minServiceQueryInterval);
            
            lastServiceQueryTime = DateTime.Now;

            WundergroundWeatherUri uri = new WundergroundWeatherUri(location);

            string response = new WebClient().DownloadString(uri.ToString());

            Assert.IsNotNull(response);
            Assert.IsTrue(response.Length > 0);

            WundergroundWeatherData weatherData = responseAnalyzer.Analyze(response);

            Assert.IsTrue(
                EqualityChecker.AreAllFieldsNotNull<WundergroundWeatherData>(weatherData, "VisibilityMi", "VisibilityKm")
                );
            
            Assert.AreEqual(response, weatherData.SourceXml);
        }

        private void Forecast(string location)
        {
            if (lastServiceQueryTime.HasValue && (DateTime.Now - lastServiceQueryTime.Value).TotalSeconds < 4)
                Thread.Sleep(4 * 1000);

            lastServiceQueryTime = DateTime.Now;

            WundergroundWeatherForecastUri uri = new WundergroundWeatherForecastUri(location);

            string response = new WebClient().DownloadString(uri.ToString());

            Assert.IsNotNull(response);
            Assert.IsTrue(response.Length > 0);

            WundergroundWeatherForecastsData weatherData = responseAnalyzer.AnalyzeForecast(response);

            Assert.IsTrue(
                EqualityChecker.AreAllFieldsNotNull<WundergroundWeatherForecastsData>(weatherData)
                );

            Assert.IsTrue(weatherData.Forecasts.Count > 0);

            Assert.IsTrue(
                EqualityChecker.AreAllCollectionElementFieldsNotNull<WundergroundWeatherForecastData>(weatherData.Forecasts)
                );

            Assert.AreEqual(response, weatherData.SourceXml);
        }
    }
}
